 
/* Autores:
    Medina Ojosnegros, Javier
    Gutiérrez Rodríguez, David
*/

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Terminal {

    // Atributos
    private static Scanner sc;
    private BufferedReader lector;
    private List<Ticket> tickets;
    private Deposito deposito;
    private Ubicacion ubicacion;

    // Constructor
    public Terminal(Deposito deposito, List<Ticket> tickets, Ubicacion ubicacion) throws IOException, ParseException {
        this.tickets = tickets;
        this.deposito = deposito;
        this.ubicacion = ubicacion;
        iniciarTerminal();
    }

    // Métodos
    public void iniciarTerminal() throws IOException, ParseException {
        sc = new Scanner(System.in);
        char sel;
        do {
            menu();
            sel = sc.next().toLowerCase().charAt(0);
            switch (sel) {
                // Entrada al parking
                case '1':
                    // Antes de entrar se comprueba si hay plazas libres
                    if (!ubicacion.parkingLibre()) {
                        System.out.println("Parking lleno");
                    } 
                    // Si el parking está libre, se hace lo siguiente: pedir al usuario la matrícula, crear un objeto Ticket para esa matrícula, asignarle la 1ª ubicación libre, añadir el objeto Ticket al ArrayList, mostrar el ticket (incluyendo la hora de entrada), y mosrtar el estado actual del plano del parking
                    else {
                        String matricula = pedirMatricula(); 
                        mostrarGenerando();
                        Ticket t = new Ticket(matricula);
                        ubicacion.asignarUbicacion(t);      
                        tickets.add(t);                   
                        System.out.print(tickets.get(t.getId()-1));                                                                    // Muestra parte de la información del ticket actual
                        System.out.print("Ubicación: Planta " + t.getPlanta(ubicacion) + ", Plaza " + t.getPlaza(ubicacion) + "}\n");  // Muestra el resto de la información del ticket actual
                        ubicacion.mostrarUbicaciones();
                    }
                    System.out.println();
                    break;
                // Salida del parking    
                case '2':
                    double importe = 0;
                    double[] cantidad = new double[6];
                    int id = 0,
                     i = 0;
                    lector = new BufferedReader(new InputStreamReader(System.in));
                    //Buscamos el ticket
                    boolean correcto;
                    do {
                        correcto = true;
                        try {
                            System.out.print("\nIntroduzca ticket (id): ");
                            id = Integer.parseInt(lector.readLine());
                        } catch (NumberFormatException ex) {
                            System.out.println("Introduzca dígitos");
                            correcto = false;
                        }
                    } while (!correcto);         
                    //si no lo encontramos mostramos mensaje de error
                    if (!ubicacion.existeTicket(id)){
                        System.out.println("Ticket ilegible\n");
                    }   
                    else{
                        //Calculamos el tiempo que ha pasado el coche en el parking y su coste
                        Ticket actual = null;
                        actual = tickets.get(id-1);
                        Date hora1 = actual.getFechaHora();
                        Date hora2 = new Date();
                        double milis_ticket1 = hora1.getTime();
                        double milis_ticket2 = hora2.getTime();
                        double milis_ticket3 = (milis_ticket2 - milis_ticket1) / 1000 / 60;
                        double total = (int) Math.ceil(milis_ticket3) * 0.5;
                        System.out.println("Total a pagar: " + total + "€");
                        int[] introducido = new int[6];
                        introducido = introducirDinero(introducido); // método que recibe un array con el nº de los distintos valores de monedas y lo devuelve correctamente rellenado con las cantidades de cada una que ha introducido el usuario
                        
                        //Calculamos el importe que ha introducido el usuario+
                        double acumulado = 0;
                        acumulado += introducido[0] * 0.05;
                        acumulado += introducido[1] * 0.10;
                        acumulado += introducido[2] * 0.20;
                        acumulado += introducido[3] * 0.50;
                        acumulado += introducido[4] * 1.00;
                        acumulado += introducido[5] * 2.00;
                        boolean continuar = true;
                        if (acumulado < total) {
                            continuar = false;
                            System.out.println("No ha introducido suficiente dinero\n");
                        } else {
                            //Metemos las monedas introducidas en el deposito
                            deposito.introducirMonedas(introducido);

                            //Mostramos el deposito actual de monedas
                            System.out.println("\nDepósito: " + deposito.toString());
                            
                            //Calculamos si hay que devolver monedas
                            deposito.resetCantidades();
                            importe = acumulado - total;
                            importe = deposito.calcularMonedas(importe, 2.0);
                            importe = deposito.calcularMonedas(importe, 1.0);
                            importe = deposito.calcularMonedas(importe, 0.5);
                            importe = deposito.calcularMonedas(importe, 0.2);
                            importe = deposito.calcularMonedas(importe, 0.1);
                            importe = deposito.calcularMonedas(importe, 0.05);
                            
                            cantidad = deposito.getCantidades();

                            System.out.print("Vuelta: {0.05 0.10 0.20 0.50 1.0 2.0}: ");
                            for (i = 0; i < 6; i++) {
                                System.out.print((int) cantidad[i] + " ");
                            }
                            System.out.println("");

                            //Mostramos el deposito actual de monedas
                            System.out.println("Depósito: " + deposito.toString());
                            int planta, plaza;
                            planta=ubicacion.obtenerPlanta(id);
                            plaza=ubicacion.obtenerPlaza(id);
                            ubicacion.liberarUbicacion(planta, plaza);
                            System.out.println("Buen Viaje!!\n");
                        }
                    }
                    break;
                default:
                    System.out.println(" Selección incorrecta \n");
            }
        } while (sel > 0);
    }

    public static void menu() {
        System.out.println("    PARKING BLUE-ZONE");
        System.out.println("**************************");
        System.out.println("* (1) Entrar al parking  *");
        System.out.println("* (2) Salir del parking  *");
        System.out.println("**************************");
        System.out.print(" Seleccione botón: ");
    }

    public String pedirMatricula() {
        sc = new Scanner(System.in);
        System.out.print("\nVerificando matrícula: ");
        String matricula = sc.next();
        return matricula;
    }

    public void mostrarGenerando() {
        try {
            System.out.print("Generando ticket.");
            for (int i = 0; i < 2; i++) {
                Thread.sleep(700);
                System.out.print(".");
            }
            Thread.sleep(900);
            System.out.println();
        } catch (InterruptedException ex) {
            Logger.getLogger(Maquina.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    // Este método controla que sea correcto lo introducido en el array que ha de guardar las cantidades de cada tipo de moneda que va a introducir el usuario
    public int[] introducirDinero(int[] introducido){   
        boolean tecleadoOK = false; 
        String dinero="";
        
        do{    
            System.out.print("Introduzca dinero (0.05 0.10 0.20 0.50 1.0 2.0): ");
            try {
                dinero = lector.readLine();
            } catch (IOException ex) {
                Logger.getLogger(Terminal.class.getName()).log(Level.SEVERE, null, ex);
            }

            int contEspacios = 0 ;
            int contDigitosMinimos = 0;
            boolean caracSonDigitos = true;
            
            for (int i = 0; i < dinero.length(); i++) {
                if ( dinero.charAt(i) != ' ') {  
                    if( !Character.isDigit(dinero.charAt(i)) ) {
                        caracSonDigitos = false;
                    }
                    else{
                        contDigitosMinimos++;
                    }
                }
                else if (dinero.charAt(0) != ' ' && dinero.charAt( dinero.length()-1 ) != ' ') {    // que no haya espacio en la primera posición ni al final     i != dinero.length()-1
                        if (i != 0 && i != dinero.length()-1 ){                                     // si no se está evaluando la primera ni última posición (para que no dé error de salida del array en la siguiente línea de código)
                            if (dinero.charAt(i-1) != ' ' && dinero.charAt(i+1) != ' ') {           // que en la posición anterior y posterior al espacio tampoco haya más espacios
                                contEspacios++;
                            }
                        }
                }
            }

            String ceros = "0 0 0 0 0 0";
            if (!dinero.equals(ceros) && contEspacios == 5 && caracSonDigitos && contDigitosMinimos >= 6){  
                tecleadoOK = true;
            }
            else{   
                System.out.println("Introducción errónea. Introduzca dígitos, uno por cada tipo de moneda (mínimo '0') y un espacio entre cada dígito (5 en total)\n"); 
            }
        }while(!tecleadoOK);    
        
        String acum="";
        int j = 0; 

        for (int i = 0; i < dinero.length(); i++) {
            char carActual = dinero.charAt(i);
            if (carActual != ' ' && (i < dinero.length()-1)) {
                acum+= carActual;
            }
            else if (carActual == ' ' && (i < dinero.length()-1)) {
                introducido[j] = Integer.parseInt(acum);
                j++;
                acum = "";
            } 
            else{ //es el último caracter y por tanto el 'for' no va a hacer más pasadas, con lo cual no se guarda el último 'acum' en la última posición por rellenar del array
                introducido[j] = Integer.parseInt(acum + (dinero.charAt(dinero.length()-1)) );
            }
        } 
        return introducido;
    }
    
}

